package com.hyper_yang.javase.supplement;

import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.*;
import java.time.format.DateTimeFormatter;
import java.time.format.FormatStyle;
import java.time.temporal.TemporalAccessor;
import java.util.Calendar;
import java.util.Date;

/* StringBuilder:  since jdk 1.5
 * 当对字符串要做频繁的修改的时候，建议使用 StringBuilder: 可变字符串对象
 * byte[] value, 没有final，可改变
 *      初始容量: 16
 *
 * StringBuffer: (仅不同点) since jdk 1.0
 *      stringbuffer 所有方法都有 synchronized  【线程安全】
 */
public class StringBuilderTest {
    @DisplayName("StringBuilder")
    @Test
    public void test01() {
        StringBuilder strBuilder = new StringBuilder("abcd");
        strBuilder.append("a");
        strBuilder.append("dc");
        System.out.println(strBuilder.indexOf("ad"));
        System.out.println(strBuilder);
        strBuilder.setCharAt(4, '不');
        strBuilder.charAt(3);
        strBuilder.delete(2, 4); // [ )
        String str = strBuilder.toString();
        System.out.println(str);
    }

    @DisplayName("包装类细节--缓冲区")
    @Test
    public void integerTest() {
//        Double d1 = 100;  ❌
        Double d2 = Double.valueOf(100);

        // 下面程序出现 "奇怪结果" 的原因，整数类型存在缓冲区
        Integer i1 = 100;
        Integer i2 = 100;
        Integer i3 = Integer.valueOf(100);
        System.out.println(i1 == i2);
        System.out.println(i1 == i3);
        Integer i4 = 100000;
        Integer i5 = 100000;
        Integer i6 = Integer.valueOf(100000);
        System.out.println(i4 == i5);
        System.out.println(i4 == i6);
    }

    @DisplayName("Date测试: ")
    @Test
    public void dateTest() {
        Date date = new Date();
        System.out.println(date);
        System.out.println(date.getYear()); // 1900年
        System.out.println(date.getTime()); // 1970年
        System.out.println(date.toLocaleString());
    }

    @DisplayName("Calendar测试: ")
    @Test
    public void calendarTest() { //abstract class  ctrl + h
        Calendar calendar = Calendar.getInstance();
        System.out.println(calendar);

        int i = calendar.get(Calendar.YEAR);
        System.out.println(i);
        int i2 = calendar.get(Calendar.DAY_OF_WEEK); // 这是按国外的
        System.out.println(i2);
    }

    @DisplayName("SimpleDateFormat测试: ")
    @Test
    public void simpleDateFormatTest() throws ParseException {
        // todo: 日期 -> 指定格式的字符串
        Date date = new Date();
        System.out.println(date);

        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd E");
        String format = simpleDateFormat.format(date);
        System.out.println(format);
        System.out.println("------------------------------------");
        // todo: 日期 -> 指定格式的字符串
        String s = "2025-05-01";
        SimpleDateFormat simpleDateFormat1 = new SimpleDateFormat("yyyy-MM-dd");
        Date parseDate = simpleDateFormat1.parse(s);
        System.out.println(parseDate);
    }

    @DisplayName("java.time测试: ") // 【推荐使用】
    @Test
    public void timeTest() {
        String illustrate = """
                新项目优先使用 java.time 包 (Java 8+)
                避免使用老旧的 Date 和 Calendar 类
                明确区分使用时区：
                不需要时区：LocalDate/LocalTime/LocalDateTime
                需要时区：ZonedDateTime
                格式化时考虑线程安全：使用 DateTimeFormatter 而非 SimpleDateFormat
                数据库交互：
                JDBC 4.2+ 直接支持 java.time 类型
                旧版本可转换为 java.sql.Date/Timestamp
                """;
        // localDate
//        System.out.println(LocalDate.now());
        LocalDate localDate = LocalDate.of(2004, 3, 27);
//        System.out.println(localDate);
        // LocalDateTime
//        System.out.println(LocalDateTime.now()); // 精确到纳秒
        // LocalTime
//        System.out.println(LocalTime.now());
        // todo: of get plus minus
        LocalDate today = LocalDate.now();
        LocalDate date = LocalDate.of(2023, Month.JUNE, 15);
        int year = date.getYear();  // 2023
        Month month = date.getMonth();  // JUNE
        int day = date.getDayOfMonth();  // 15
        LocalDate nextWeek = today.plusWeeks(1);
        boolean isLeap = date.isLeapYear();  // 是否闰年

        LocalTime now = LocalTime.now();
        LocalTime time = LocalTime.of(14, 30, 45);  // 14:30:45
        int hour = time.getHour();  // 14
        int minute = time.getMinute();  // 30
        LocalTime nextHour = time.plusHours(1);

        LocalDateTime ldt = LocalDateTime.now();
        LocalDateTime dt = LocalDateTime.of(2023, 6, 15, 14, 30);
        LocalDateTime nextMonth = dt.plusMonths(1);

        ZonedDateTime zdt = ZonedDateTime.now(ZoneId.of("Asia/Shanghai"));
        ZonedDateTime nyTime = zdt.withZoneSameInstant(ZoneId.of("America/New_York"));
        ZoneId zone = zdt.getZone();  // 获取时区

        Instant now1 = Instant.now();  // 获取当前时间戳
//        System.out.println(now1);
        Instant later = now1.plusSeconds(360);  // 360秒后
//        System.out.println(later);
//        System.out.println(later.minusSeconds(360));
        long epochMilli = now1.toEpochMilli();  // 获取毫秒时间戳

        // todo: period durations
        Period period = Period.between(LocalDate.now(),LocalDate.now().plusMonths(3).plusYears(1));
//        System.out.println(period);  // P3M
//        System.out.println(period.getMonths()); // 3
//        System.out.println(period.toTotalMonths()); // 15

        Duration duration = Duration.between(LocalDateTime.now(),LocalDateTime.now().plusSeconds(20).plusDays(3));
//        System.out.println(duration);
//        System.out.println(duration.getSeconds());
//        System.out.println(duration.toHours());
//        System.out.println(duration.toDays());
//        System.out.println(duration.toSeconds());


        LocalDateTime now3 = LocalDateTime.now();
        // todo: 日期转字符串
        // 预定义标准格式
        DateTimeFormatter isoDateTime = DateTimeFormatter.ISO_DATE_TIME; // final
        String format1 = isoDateTime.format(now3);
//        System.out.println(format1);
        // 本地化相关格式
        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofLocalizedDate(FormatStyle.MEDIUM); // MEDIUM type: enum
//        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofLocalizedDate(FormatStyle.FULL).withZone(ZoneId.systemDefault()); // MEDIUM type: enum
        String format2 = dateTimeFormatter.format(now3);
//        System.out.println(format2);
        // 自定义格式
        DateTimeFormatter patternFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss E");
        String format3 = patternFormatter.format(now3);
//        System.out.println(format3);


        // todo: 字符串转日期
        String str = "2024-08-07 10:29:10 周三";

        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss E"); // 如果字符串是 2024-08-07T10:29:10这种形式的，可以不写 formatter

        LocalDateTime localDateTime = LocalDateTime.parse(str, formatter);

        System.out.println(localDateTime);
    }
}
